//
// Created by none98 on 2021/9/16.
//

#ifndef LOGINSERVER_GAMESERVER_H
#define LOGINSERVER_GAMESERVER_H

#include <memory>
#include <TcpConnection.h>
#include <unordered_map>
#include <boost/asio/thread_pool.hpp>
#include "TcpServer.h"
#include "DatabaseConnPool.h"

class Dispatcher;
class LoginService;
class Service;
class GameServer {
    friend class Context;
public:
    enum ProtoType{
        loginReq = 1,
        loginRes,
        logoutReq,
        logoutRes,
        chooseRoleReq,
        chooseRoleRes,
        createRoleReq,
        createRoleRes,
        moveReq,
        moveRes
    };

    enum StatusCode{
        success = 0,
        failed,
        authFailed
    };
    GameServer();
    ~GameServer();


    void Handle(int type,Service* service);
    void SetDatabase(const std::string &hostname, const std::string &username, const std::string &password);

    void Start(const std::string &address, int port);



private:
    void OnMessage(TcpConnectionPtr conn,Buffer* inputBuffer);
    void OnConnection(TcpConnectionPtr conn);
    void OnClose(TcpConnectionPtr conn);

    void SubmitTask(const std::function<void()> &func);
    void Login(long uid, TcpConnectionPtr conn);


    boost::asio::thread_pool pool;

    std::unique_ptr<TcpServer> tcpServer;
    std::unique_ptr<Dispatcher> dispatcher;

    std::mutex consMutex;
    std::unordered_map<long,TcpConnectionPtr> connections;

    std::unique_ptr<DatabaseConnPool> dbConnectionsPool;
};


#endif //LOGINSERVER_GAMESERVER_H
